﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Windows.Markup;
using System.Windows;
using System.Linq;
using Sinacor.Infra.Tools.LanguageCompiler;
using Infra.LanguageGenerator;

namespace Sinacor.Infra.Tools.LanguageGenerator
{
    public class XMLLanguageGenerator
    {
        
      string resourceHeader = "<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"" + "\r\n" +
                              "    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">" + "\r\n" +
                              "    <ResourceDictionary.MergedDictionaries>" + "\r\n" +
                              "        <ResourceDictionary>" + "\r\n" +
                              "            <ResourceDictionary.MergedDictionaries>" + "\r\n";

      string resourceFooter = "            </ResourceDictionary.MergedDictionaries>" + "\r\n" +
                              "        </ResourceDictionary>" + "\r\n" +
                              "    </ResourceDictionary.MergedDictionaries>" + "\r\n" +
                              "</ResourceDictionary>";


        /// <summary>
        /// Gera arquivos XMLs de Languages
        /// </summary>
        /// <param name="compileProject">Indica se o projeto será compilado após a geração dos XMLs</param>
        public void GenerateLanguageXML(bool compileProject)
        {
            Log.Instance.Escreve("Gerando o XML do Projeto");

            ModulesList modules = new ModulesList();
            bool errorSave = false;
            DataAccess dataAccess = new DataAccess();

            Log.Instance.Escreve("Obtendo os Idiomas ");
            List<LanguageInfo> languages = dataAccess.GetLanguages();

            List<string> allFilesCreated = new List<string>();

            CreateLanguageProject();
            CreateBatFile();

            foreach (LanguageInfo language in languages)
            {
                List<string> languageFile = new List<string>();

                foreach (string module in modules.Modules)
                {
                    try
                    {
                        //Gera XAMLs
                        Log.Instance.Escreve("Obtendo os Arquivos com o idioma " + language.Codigo + " e módulo " + module);
                        List<XamlInfo> xamls = dataAccess.GetLanguageXAML(module, language.Codigo);

                        //Cria Arquivos com mensagens de Languages
                        Log.Instance.Escreve("Salvando os Arquivos com o idioma " + language.Codigo + " e módulo " + module);
                        List<string> createdFiles = SaveXamls(xamls, module, language.Sigla, ref allFilesCreated);

                        if (createdFiles.Count > 0)
                        {
                            //Cria Arquivo que une todos os arquivos de language do módulo
                            string languageFileCreated = SaveXamlModule(createdFiles, module, language.Sigla);

                            allFilesCreated.Add(module + @"\" + languageFileCreated);

                            //armazena todos os arquivos gerados para criar o arquivo pai de language
                            languageFile.Add(module + "/" + languageFileCreated);
                        }

                    }
                    catch (Exception ex)
                    {
                        errorSave = true;
                        System.Windows.Forms.MessageBox.Show(ex.Message.ToString(), "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                    }
                }

                if (!errorSave)
                {
                    if (languageFile.Count > 0)
                    {
                        string fileXamlLanguageCreated = SaveXamlLanguage(languageFile, language.Sigla);
                        allFilesCreated.Add(fileXamlLanguageCreated) ;
                    }

                }
                else
                    break;
            }

            if (compileProject && !errorSave)
            {
                Compile objCompile = new Compile();
                objCompile.CompileLanguageProject(true, allFilesCreated);
            }
        }

        private void CreateLanguageProject()
        {

            Log.Instance.Escreve("Criando o Projeto");

            try
            {
                string moduleFolder = System.Windows.Forms.Application.StartupPath + @"\Languages";

				if (Directory.Exists(moduleFolder))
					Directory.Delete(moduleFolder, true);

                Log.Instance.Escreve("Criando a pasta do Projeto: " + moduleFolder);
                Directory.CreateDirectory(moduleFolder);

                StreamWriter SW;

                SW = File.CreateText(moduleFolder + @"\Languages.csproj");
                SW.Write(LanguageProject.Languages_xml.ToString());

                SW.Close();
                SW.Dispose();

                Log.Instance.Escreve("Criando a bat de Compilação");
                SW = File.CreateText(moduleFolder + @"\Compile.bat");
                SW.Write(LanguageProject.Compile.ToString());

                SW.Close();
                SW.Dispose();

            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message.ToString(), "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        private string SaveXamlLanguage(List<string> createdFiles, string languageFolder)
        {
            Log.Instance.Escreve("Montando e Salvando os arquivos de Resource na pasta " + languageFolder);

            string moduleFolder = System.Windows.Forms.Application.StartupPath + @"\Languages" ;
            string fileToCreate = "Languages_" + languageFolder.Replace("-", "_") + ".xaml";
            string createdFile = "";
            string fileBody = "";

            ResourceDictionary resource = new ResourceDictionary();

            //File.Delete(moduleFolder + @"\" + fileToCreate);

            fileBody = resourceHeader;

            foreach (string file in createdFiles)
            {
                fileBody += "                <ResourceDictionary Source=\"" + file + "\"/>" + "\r\n";

            }

            fileBody += resourceFooter;

            StreamWriter SW;
            SW = File.CreateText(moduleFolder + @"\" + fileToCreate);
            SW.Write(fileBody);
            SW.Close();
            SW.Dispose();

            createdFile = fileToCreate;

            return createdFile;

        }

        private string SaveXamlModule(List<string> createdFiles, string module, string languageFolder)
        {
            Log.Instance.Escreve("Salvando os arquivos XAML do módulo " + module + " na pasta " + languageFolder);

            string moduleFolder = System.Windows.Forms.Application.StartupPath + @"\Languages\" + module;
            string fileToCreate = module + "_" + languageFolder.Replace("-", "_") + ".xaml";
            string createdFile = "";
            string fileBody = "";

            ResourceDictionary resource = new ResourceDictionary();

            //File.Delete(moduleFolder + @"\" + fileToCreate);    

            fileBody = resourceHeader;

            foreach (string file in createdFiles)
            {
                fileBody += "                <ResourceDictionary Source=\"" + file + "\"/>" + "\r\n";

            }

            fileBody += resourceFooter;

            StreamWriter SW;
            SW = File.CreateText(moduleFolder + @"\" + fileToCreate);
            SW.Write(fileBody);
            SW.Close();
            SW.Dispose();

            createdFile = fileToCreate;

            return createdFile;

        }

        private List<string> SaveXamls(List<XamlInfo> xamls, string module, string languageFolder, ref List<string> allFilesCreated)
        {
            Log.Instance.Escreve("Salvando todos os arquivos XAML do módulo " + module + " na pasta " + languageFolder);
            
            string moduleFolder = System.Windows.Forms.Application.StartupPath + @"\Languages\" + module;
            string languageFolderFull = moduleFolder + @"\" + languageFolder;
            List<string> filesCreated = new List<string>();

            //Verifica se diretório existe, caso não exista - apaga para recriar
			//if (Directory.Exists(moduleFolder))
			//    Directory.Delete(moduleFolder,true);    

            //recria os diretórios limpos
            Directory.CreateDirectory(moduleFolder);
            Directory.CreateDirectory(languageFolderFull);

            foreach (XamlInfo xamlInfo in xamls)
            {
                StreamWriter SW;
                SW = File.CreateText(languageFolderFull + @"\" + module + "." + xamlInfo.SubModulo + "_" + languageFolder.Replace("-","_") + ".xaml");
                SW.Write(xamlInfo.XamlBody);
                SW.Close();
                SW.Dispose();

                filesCreated.Add(languageFolder + "/" + module + "." + xamlInfo.SubModulo + "_" + languageFolder.Replace("-", "_") + ".xaml");
                allFilesCreated.Add(module + @"\" + languageFolder + @"\" + module + "." + xamlInfo.SubModulo + "_" + languageFolder.Replace("-", "_") + ".xaml");
            }

            return filesCreated;

        }

        private void CreateBatFile()
        {

            //Sempre executa da pasta onde fica os módulos...
            string folderPath = System.Windows.Forms.Application.StartupPath + @"\Languages\";
            
            //Path do Projeto language
            string languageProject = System.IO.Path.Combine(folderPath, "Languages.csproj");

            string rootPath = System.Environment.GetEnvironmentVariable("windir");

            //Caminho do compilador
            string msbuild =  System.IO.Path.Combine(rootPath, @"Microsoft.NET\Framework\v3.5\MSBuild.exe");

            //Parâmetros para a compilação
            string parameters = "/property:Configuration=Release";

            string batPath = System.IO.Path.Combine(folderPath, "Compile.bat");

            string batBody = string.Format("{0} \"{1}\" {2}", msbuild, languageProject, parameters);

            Log.Instance.Escreve("Criando a bat de Compilação em: " + batPath);
            Log.Instance.Escreve("Criando a bat de Compilação com conteúdo: " + batBody);
            
            StreamWriter SW;
            SW = File.CreateText(batPath);
            SW.Write(batBody);
            SW.Close();
            SW.Dispose();
        }
    }
}
